package org.dromara.oce.domain;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.dromara.oce.utils.CommonConstants;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;


/**
 * @desc:推广记录每日数据记录表
 * @autor: hhl
 * @date: 2024-10-17 17:49:02<br>
 */
@Data
@EqualsAndHashCode()
@Accessors(chain = true)
@TableName("oce_advertiser_everyday_cost")
public class OceAdvertiserEverydayCost implements Serializable {

    //巨量广告主每日消耗记录id
    @TableId(type = IdType.AUTO)
    private Long advertiserCostId;

    //推广链接id
    private Long referralLinkId;

    //推广链接类型：1-袋鼠；2-番茄；3-点众；4-番茄IAA；5-袋鼠IAA；6-端原生IAP；7-端原生IAA；
    private Integer referralLinkType;

    //巨量应用平台编码
    private String thirdAdvertiserAppCode;

    //第三方广告主id
    private String thirdAdvertiserId;

    //广告主账户名
    private String thirdAdvertiserName;

    //当日时间戳
    private Long thatdayTimestamp;

    //当日日期
    private String thatdayDate;

    //短剧名称
    private String dramaTitle;

    //总消耗
    private BigDecimal cost = BigDecimal.ZERO;

    //展示数
    @TableField(value = "`show`")
    private Integer show = 0;

    //平均千次展现费用=总花费/展示数*1000
    @TableField(value = "avg_show_cost")
    private BigDecimal avgShowCost = BigDecimal.ZERO;

    //点击数
    private Integer click = 0;

    //平均点击单价=总花费/点击数
    private BigDecimal avgClickCost = BigDecimal.ZERO;

    //点击率=点击数/展示数*100%
    private BigDecimal ctr = BigDecimal.ZERO;

    //转化数=付费数*回传率
    @TableField(value = "`convert`")
    private Integer convert = 0;

    //转化成本
    private BigDecimal convertCost = BigDecimal.ZERO;

    //转化率=转化数/点击数*100%
    private BigDecimal convertRate = BigDecimal.ZERO;

    //激活数
    private Integer active = 0;

    //激活成本=总消耗/激活数
    private BigDecimal activeCost = BigDecimal.ZERO;

    //激活率=激活数/点击数*100%
    private BigDecimal activeRate = BigDecimal.ZERO;

    //首次付费数
    private Integer activePay = 0;

    //首次付费成本=消耗/付费次数
    private BigDecimal activePayCost = BigDecimal.ZERO;

    //首次付费率=首次付费数/激活数
    private BigDecimal activePayRate = BigDecimal.ZERO;

    //付费次数
    private Integer gamePayCount = 0;

    //付费成本=消耗/付费次数
    private BigDecimal gamePayCost = BigDecimal.ZERO;

    //当日总收入
    private BigDecimal thatdayTotalAmount = BigDecimal.ZERO;

    //当日分成金额
    @Deprecated
    private BigDecimal thatdayDividendAmount = BigDecimal.ZERO;

    //当日注册用户的总收入
    private BigDecimal thatdayRegisterTotalAmount = BigDecimal.ZERO;

    //当日注册用户的分成金额
    @Deprecated
    private BigDecimal thatdayRegisterDividendAmount = BigDecimal.ZERO;

    //当日IAA总收入
    private BigDecimal iaaTotalAmount = BigDecimal.ZERO;

    //当日IAA分成金额
    private BigDecimal iaaDividendAmount = BigDecimal.ZERO;

    //当日注册用户的IAA总收入
    private BigDecimal iaaRegisterTotalAmount = BigDecimal.ZERO;

    //当日注册用户的IAA分成金额
    private BigDecimal iaaRegisterDividendAmount = BigDecimal.ZERO;

    //当日利润金额=当日分成金额-当日消耗
    private BigDecimal thatdayProfitAmount = BigDecimal.ZERO;
    /**
     * 当日注册用户的利润金额
     */
    private BigDecimal thatdayRegisterProfitAmount = BigDecimal.ZERO;

    //当日总支付笔数
    private Integer thatdayPaidTotalNum = 0;

    //当日付款人数
    private Integer thatdayPaidUseNum = 0;

    //消耗时速
    private BigDecimal costHoursSpeed = BigDecimal.ZERO;

    //投手名称
    private String createName;

    //应用类型：1-抖小；3-微小；
    private Integer appType;

    //创建者
    private String createBy;

    //创建时间
    private LocalDateTime createTime;

    //部门id
    private Long deptId;

    /**
     * 回本率
     * IAP回本率 = 总分成金额 / 总消耗金额
     * IAA回本率=（总分成金额+广告总分成金额）/ 总消耗金额
     */
    private BigDecimal extRecoveryRate = BigDecimal.ZERO;

    /**
     * 新增回本率
     * 新增回本率 = （总新增分成金额+广告总新增分成金额）/总消耗金额
     */
    private BigDecimal extRegisterRecoveryRate = BigDecimal.ZERO;

    /**
     * 客单价
     * IAP客单价 = 当日充值分成金额 / 付费人数
     * IAA客单价 = 当日广告分成 / 转化数
     */
    private BigDecimal extAvgPrice = BigDecimal.ZERO;

    /**
     * 付费成本
     * IAP付费成本 = 消耗 / 付费人数
     * IAA付费成本 = 消耗 / 激活数
     */
    private BigDecimal extPayCost = BigDecimal.ZERO;

    /**
     * 回传率
     * 回传率 = 转化数 / 当日付款人数
     */
    private BigDecimal returnRate = BigDecimal.ZERO;

    /**
     * 当日LTV
     */
    private BigDecimal attributionMicroGame0dLtv = BigDecimal.ZERO;

    /**
     * 当日广告变现ROI
     */
    private BigDecimal attributionMicroGame0dRoi = BigDecimal.ZERO;


    //商务当日分成金额
    private BigDecimal thatdayDividendAmountSw = BigDecimal.ZERO;
    //商务当日注册用户的分成金额
    private BigDecimal thatdayRegisterDividendAmountSw = BigDecimal.ZERO;
    //商务当日IAA分成金额
    private BigDecimal iaaDividendAmountSw = BigDecimal.ZERO;
    //商务当日注册用户的IAA分成金额
    private BigDecimal iaaRegisterDividendAmountSw = BigDecimal.ZERO;
    //商务当日利润金额=商务当日分成金额-当日消耗/1.015
    private BigDecimal thatdayProfitAmountSw = BigDecimal.ZERO;
    //商务当日新增利润=商务当日注册用户的分成金额-当日消耗/1.015
    private BigDecimal thatdayRegisterProfitAmountSw = BigDecimal.ZERO;


    /**
     * 计算分成时，袋鼠iaa和iap都需要在订单金额减掉通道费之后，再*0.92 2025.03.25 飞鸿要求的
     * 计算袋鼠iaa和iap分成金额时，删除扣点，2025.05.12大风要求的
     * 计算订单分成金额（袋鼠、番茄iaa，袋鼠iaa）
     */
    public static BigDecimal computeDividendAmount(Integer referralLinkType, Integer appType, BigDecimal payAmount) {
        if (CommonConstants.REFERRAL_LINK_TYPE_SELF.intValue() == referralLinkType) {//袋鼠
            //袋鼠   微小  0.9个点，抖小0.99   利润  = 分成 - 消耗
            if (CommonConstants.REFERRAL_APP_TYPE_DOUYIN == appType) {
//                return payAmount.multiply(new BigDecimal("0.99")).multiply(new BigDecimal("0.92")).setScale(4, RoundingMode.HALF_UP);
                return payAmount.setScale(4, RoundingMode.HALF_UP);
            } else if (CommonConstants.REFERRAL_APP_TYPE_KUAISHOU.intValue() == appType) {

            } else if (CommonConstants.REFERRAL_APP_TYPE_WECHAT.intValue() == appType) {
//                return payAmount.multiply(new BigDecimal("0.9")).multiply(new BigDecimal("0.92")).setScale(4, RoundingMode.HALF_UP);
                return payAmount.setScale(4, RoundingMode.HALF_UP);
            }
        } else if (CommonConstants.REFERRAL_LINK_TYPE_FANQIE.intValue() == referralLinkType) {//番茄那里会有计算方式
        // 已废弃
        }
        return BigDecimal.ZERO;
    }

    /**
     * 计算商务袋鼠分成金额
     * @param referralLinkType
     * @param appType
     * @param payAmount
     * @return
     */
    public static BigDecimal computeDividendAmountSw(Integer referralLinkType, Integer appType, BigDecimal payAmount) {
        if (CommonConstants.REFERRAL_LINK_TYPE_SELF.intValue() == referralLinkType) {//袋鼠
            //袋鼠   微小  0.9个点，抖小0.99   利润  = 分成 - 消耗
            if (CommonConstants.REFERRAL_APP_TYPE_DOUYIN == appType) {
                return payAmount.multiply(new BigDecimal("0.99")).setScale(4, RoundingMode.HALF_UP);
            } else if (CommonConstants.REFERRAL_APP_TYPE_KUAISHOU.intValue() == appType) {//没有用

            } else if (CommonConstants.REFERRAL_APP_TYPE_WECHAT.intValue() == appType) {
                return payAmount.multiply(new BigDecimal("0.9")).setScale(4, RoundingMode.HALF_UP);
            }
        } else if (CommonConstants.REFERRAL_LINK_TYPE_FANQIE.intValue() == referralLinkType) {//番茄那里会有计算方式
            // 已废弃
        }
        return BigDecimal.ZERO;
    }

    /**
     * 计算番茄扣点分成金额
     *
     * @param appType
     * @param payAmount
     * @param devicePlatform
     * @return
     */
    public static BigDecimal computeFqDividendAmount(Integer appType, BigDecimal payAmount, String devicePlatform) {
        BigDecimal dividendAmount = BigDecimal.ZERO;
        if (appType == 1) {//抖小
            dividendAmount = payAmount.multiply(new BigDecimal("0.891"));
        } else if (appType == 3) {//微小
            if (CommonConstants.DEVICE_PLATFORM_ANDROID.equals(devicePlatform)) {//安卓支付
                dividendAmount = payAmount.multiply(new BigDecimal("0.801"));
            } else if (CommonConstants.DEVICE_PLATFORM_IOS.equals(devicePlatform)) {//ios支付
                dividendAmount = payAmount.multiply(new BigDecimal("0.891"));
            } else {
                dividendAmount = payAmount.multiply(new BigDecimal("0.801"));
            }
        }
        return dividendAmount.setScale(4,RoundingMode.HALF_UP);
    }

    /**
     * 计算分成时，袋鼠iaa和iap都需要在订单金额减掉通道费之后，再*0.92 2025.03.25 飞鸿要求的
     * 计算番茄iaa分成时，0.78改成0.88 2025.04.08 大风要求的
     * 计算袋鼠iaa和iap分成金额时，删除扣点，2025.05.12大风要求的
     * 计算IAA分成金额（番茄iaa，袋鼠iaa）
     */
    public static BigDecimal computeIaaDividendAmount(Integer referralLinkType, Integer appType, BigDecimal payAmount) {
        if (CommonConstants.REFERRAL_LINK_TYPE_FANQIE_IAA.intValue() == referralLinkType) {//番茄广告收益    分成 = 充值/0.7*0.88    利润 = 分成-消耗
//            return payAmount.multiply(new BigDecimal("0.88")).divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
            return payAmount.divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_DAISHU_IAA.intValue() == referralLinkType) {//袋鼠IAA
            if (CommonConstants.REFERRAL_APP_TYPE_DOUYIN == appType) {//分成 = 当日充值*0.99/0.7
//                return payAmount.multiply(new BigDecimal("0.99")).multiply(new BigDecimal("0.92")).divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
                return payAmount.divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
            } else {//先默认都是抖小的
//                return payAmount.multiply(new BigDecimal("0.99")).multiply(new BigDecimal("0.92")).divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
                return payAmount.divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
            }
        }
        return BigDecimal.ZERO;
    }

    public static BigDecimal computeIaaDividendAmountSw(Integer referralLinkType, Integer appType, BigDecimal payAmount) {
        if (CommonConstants.REFERRAL_LINK_TYPE_FANQIE_IAA.intValue() == referralLinkType) {//番茄广告收益    分成 = 充值/0.7*0.88    利润 = 分成-消耗
            return payAmount.multiply(new BigDecimal("0.88")).divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_DAISHU_IAA.intValue() == referralLinkType) {//袋鼠IAA
            if (CommonConstants.REFERRAL_APP_TYPE_DOUYIN == appType) {//分成 = 当日充值*0.99/0.7
                return payAmount.multiply(new BigDecimal("0.99")).divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
            } else {//先默认都是抖小的
                return payAmount.multiply(new BigDecimal("0.9")).divide(new BigDecimal("0.7"), 4, RoundingMode.HALF_UP);
            }
        }
        return BigDecimal.ZERO;
    }

    /**
     * 2025.04.11 飞鸿要求计算利润,计算分成,计算回本率使用当日新增分成代替之前的当日分成
     * 计算当日利润(袋鼠、点众、番茄、番茄IAA、袋鼠IAA)
     */
    public void computeProfitAmount() {
        BigDecimal costTemp = this.cost.divide(new BigDecimal("1.015"), 4, RoundingMode.HALF_UP);
        if (CommonConstants.REFERRAL_LINK_TYPE_SELF == this.referralLinkType) {//袋鼠
            this.thatdayProfitAmount = this.thatdayTotalAmount.subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.thatdayRegisterTotalAmount.subtract(this.cost);

            this.thatdayProfitAmountSw = this.thatdayDividendAmountSw.subtract(costTemp);
            this.thatdayRegisterProfitAmountSw = this.thatdayRegisterDividendAmountSw.subtract(costTemp);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_DAISHU_IAA == this.referralLinkType) {//袋鼠IAA,订单收益
            this.thatdayProfitAmount = this.thatdayDividendAmount.add(this.iaaDividendAmount).subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.thatdayRegisterDividendAmount.add(this.iaaRegisterDividendAmount).subtract(this.cost);

            this.thatdayProfitAmountSw = this.thatdayDividendAmountSw.add(this.iaaDividendAmountSw).subtract(costTemp);
            this.thatdayRegisterProfitAmountSw = this.thatdayRegisterDividendAmountSw.add(this.iaaRegisterDividendAmountSw).subtract(costTemp);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_FANQIE_IAA == this.referralLinkType) {//番茄IAA
            this.thatdayProfitAmount = this.thatdayDividendAmount.add(this.iaaDividendAmount).subtract(this.cost).setScale(4, RoundingMode.HALF_UP);
            this.thatdayRegisterProfitAmount = this.thatdayRegisterDividendAmount.add(this.iaaRegisterDividendAmount).subtract(this.cost).setScale(4, RoundingMode.HALF_UP);

            this.thatdayProfitAmountSw = this.thatdayDividendAmountSw.add(this.iaaDividendAmountSw).subtract(costTemp).setScale(4, RoundingMode.HALF_UP);
            this.thatdayRegisterProfitAmountSw = this.thatdayRegisterDividendAmountSw.add(this.iaaRegisterDividendAmountSw).subtract(costTemp).setScale(4, RoundingMode.HALF_UP);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_DOUYIN_ACCOUNT_IAA == this.referralLinkType) {//端原生IAA
            this.thatdayProfitAmount = this.iaaTotalAmount.subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.iaaRegisterTotalAmount.subtract(this.cost);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_CHUAN_SHAN_JIA_IAA == this.referralLinkType) {//穿山甲IAA
            this.thatdayProfitAmount = this.iaaTotalAmount.subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.iaaRegisterTotalAmount.subtract(this.cost);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_DIANZHONG == this.referralLinkType) {//点众
            this.thatdayProfitAmount = this.thatdayTotalAmount.subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.thatdayRegisterTotalAmount.subtract(this.cost);

            this.thatdayProfitAmountSw = this.thatdayDividendAmountSw.subtract(costTemp);
            this.thatdayRegisterProfitAmountSw = this.thatdayRegisterDividendAmountSw.subtract(costTemp);
        } else if (CommonConstants.REFERRAL_LINK_TYPE_FANQIE == this.referralLinkType) {//番茄
            this.thatdayProfitAmount = this.thatdayTotalAmount.subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.thatdayRegisterTotalAmount.subtract(this.cost);

            this.thatdayProfitAmountSw = this.thatdayDividendAmountSw.subtract(costTemp);
            this.thatdayRegisterProfitAmountSw = this.thatdayRegisterDividendAmountSw.subtract(costTemp);
        }else {
            this.thatdayProfitAmount = this.thatdayTotalAmount.subtract(this.cost);
            this.thatdayRegisterProfitAmount = this.thatdayRegisterTotalAmount.subtract(this.cost);

            this.thatdayProfitAmountSw = this.thatdayDividendAmountSw.subtract(costTemp);
            this.thatdayRegisterProfitAmountSw = this.thatdayRegisterDividendAmountSw.subtract(costTemp);
        }
    }

    /**
     * 判断链接类型是否为iaa模式
     *
     * @return
     */
    public boolean isReferralLinkTypeIsIAA() {
        if (CommonConstants.REFERRAL_LINK_TYPE_DAISHU_IAA == this.referralLinkType || CommonConstants.REFERRAL_LINK_TYPE_FANQIE_IAA == this.referralLinkType
        || CommonConstants.REFERRAL_LINK_TYPE_DOUYIN_ACCOUNT_IAA == this.referralLinkType || CommonConstants.REFERRAL_LINK_TYPE_CHUAN_SHAN_JIA_IAA == this.referralLinkType) {
            return true;
        }
        return false;
    }

    /**
     * 计算抖音端原生iaa收益
     */
    public void computeDouYinAppAmount(){
        try {
            if (CommonConstants.REFERRAL_LINK_TYPE_DOUYIN_ACCOUNT_IAA == this.referralLinkType || CommonConstants.REFERRAL_LINK_TYPE_CHUAN_SHAN_JIA_IAA == this.referralLinkType) {//端原生IAA、穿山甲IAA
                this.iaaTotalAmount = this.attributionMicroGame0dLtv;
                this.iaaRegisterTotalAmount = this.attributionMicroGame0dLtv;
                this.iaaDividendAmount = this.attributionMicroGame0dLtv;
                this.iaaRegisterDividendAmount = this.attributionMicroGame0dLtv;
            }
        } catch (Exception e) {
        }
    }


    /**
     * 计算 IAP回本率 = 总分成金额 / 总消耗金额
     * IAA回本率=（总分成金额+广告总分成金额）/总消耗金额
     * 计算 IAP客单价 = 当日充值分成金额 / 付费人数
     * IAA客单价 = 当日广告分成 / 激活数
     * 计算 IAP付费成本 = 消耗 / 付费人数
     * IAA付费成本 = 消耗 / 激活数
     */
    public void computeRateValue() {
        BigDecimal costTemp = cost;
        if (NumberUtil.equals(cost, BigDecimal.ZERO)) {
            costTemp = new BigDecimal("1");
        }else{
//            costTemp = costTemp.divide(new BigDecimal("1.015"), 4, RoundingMode.HALF_UP);
        }
        BigDecimal date = BigDecimal.ZERO;
        if (!isReferralLinkTypeIsIAA()) {
            date = thatdayTotalAmount.divide(costTemp, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
        } else {
            date = (iaaTotalAmount.add(thatdayTotalAmount)).divide(costTemp, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
        }
        this.setExtRecoveryRate(date);
        BigDecimal extRegisterRecoveryRate = BigDecimal.ZERO;
        if (!isReferralLinkTypeIsIAA()) {
            extRegisterRecoveryRate = thatdayRegisterTotalAmount.divide(costTemp, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
        } else {
            extRegisterRecoveryRate = (iaaRegisterTotalAmount.add(thatdayRegisterTotalAmount)).divide(costTemp, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100"));
        }
        this.setExtRegisterRecoveryRate(extRegisterRecoveryRate);
        BigDecimal extAvgPrice = BigDecimal.ZERO;
        if (!isReferralLinkTypeIsIAA()) {
            if (!ObjectUtils.isEmpty(thatdayPaidUseNum) && thatdayPaidUseNum > 0) {
                extAvgPrice = thatdayRegisterTotalAmount.divide(new BigDecimal(thatdayPaidUseNum), 2, RoundingMode.HALF_UP);
            }
        } else {
            if (!ObjectUtils.isEmpty(convert) && convert > 0) {
                extAvgPrice = iaaRegisterTotalAmount.divide(new BigDecimal(convert), 2, RoundingMode.HALF_UP);
            }
        }
        this.setExtAvgPrice(extAvgPrice);
        BigDecimal extPayCost = BigDecimal.ZERO;
        if (!isReferralLinkTypeIsIAA()) {
            if (!ObjectUtils.isEmpty(thatdayPaidUseNum)) {
                Integer thatdayPaidUseNum2 = thatdayPaidUseNum;
                if (thatdayPaidUseNum == 0) {
                    thatdayPaidUseNum2 = 1;
                }
                extPayCost = cost.divide(new BigDecimal(thatdayPaidUseNum2), 2, RoundingMode.HALF_UP);
            }
        } else {
            if (!ObjectUtils.isEmpty(active)) {
                Integer activeTemp = active;
                if (active == 0) {
                    activeTemp = 1;
                }
                extPayCost = cost.divide(new BigDecimal(activeTemp), 2, RoundingMode.HALF_UP);
            }
        }
        this.setExtPayCost(extPayCost);
        this.returnRate = this.thatdayPaidUseNum == 0?BigDecimal.ZERO:new BigDecimal(this.convert).divide(new BigDecimal(this.thatdayPaidUseNum), 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).divide(BigDecimal.ONE, 2, RoundingMode.HALF_UP);
    }

    /**
     * 是否计算时速
     */
    public boolean isExecuteComputeHoursSpeed() {
        //消耗、展现、收入大于就计算时速
        return this.cost.doubleValue() > 0 || this.show.intValue() > 0 || this.thatdayTotalAmount.doubleValue() > 0;
    }

}
